﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

//

namespace Soundless_Project
{
    class Camera2d
    {
        protected float _zoom; // Camera Zoom
        protected Matrix _transform; // Matrix Transform
        protected Vector2 _pos; // Camera Position
        protected float _rotation; // Camera Rotation
        public float offsetX, offsetY;
        private readonly Viewport _viewport;
        public Vector2 Origin { get; set; }
        private Rectangle? _limits;

        public Camera2d(Viewport viewport)
        {
            Origin = new Vector2(viewport.Width / 2.0f, viewport.Height / 2.0f);
            _viewport = viewport;
            _zoom = 1.0f;
            _rotation = 0.0f;
            _pos = Vector2.Zero;
            offsetX = offsetY = 0;
        }

        public Matrix GetViewMatrix(Vector2 parallax)
        {
            // To add parallax, simply multiply it by the position
            return Matrix.CreateTranslation(new Vector3(-_pos * parallax, 0.0f)) *
                // The next line has a catch. See note below.
                   Matrix.CreateTranslation(new Vector3(-Origin, 0.0f)) *
                   Matrix.CreateRotationZ(Rotation) *
                   Matrix.CreateScale(Zoom, Zoom, 1) *
                   Matrix.CreateTranslation(new Vector3(Origin, 0.0f));
        }

        public Rectangle? Limits
        {
            get { return _limits; }
            set
            {
                if (value != null)
                {
                    // Assign limit but make sure it's always bigger than the viewport
                    _limits = new Rectangle
                    {
                        X = value.Value.X,
                        Y = value.Value.Y,
                        Width = System.Math.Max(_viewport.Width, value.Value.Width),
                        Height = System.Math.Max(_viewport.Height, value.Value.Height)
                    };

                    // Validate camera position with new limit
                    _pos = _pos;
                }
                else
                {
                    _limits = null;
                }
            }
        }

        // Sets and gets zoom
        public float Zoom
        {
            get { return _zoom; }
            set { _zoom = value; if (_zoom < 0.1f) _zoom = 0.1f; } // Negative zoom will flip image
        }

        public float Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        // Auxiliary function to move the camera
        public void Move(Vector2 amount)
        {
            _pos += amount;
        }
        // Get set position
        public Vector2 Pos
        {
            get { return _pos; }
            set
            {
                _pos = value;

                if (Limits != null && Zoom == 1.0f && Rotation == 0.0f)
                {
                    _pos.X = MathHelper.Clamp(_pos.X, Limits.Value.X, Limits.Value.X + Limits.Value.Width - _viewport.Width);
                    _pos.Y = MathHelper.Clamp(_pos.Y, Limits.Value.Y, Limits.Value.Y + Limits.Value.Height - _viewport.Height);
                }
            }
        }



        public Matrix get_transformation(GraphicsDeviceManager graphicsDevice)
        {
            _transform = Matrix.CreateTranslation
            (
                new Vector3(-_pos.X + offsetX, -_pos.Y + offsetY, 0)) *
                Matrix.CreateRotationZ(_rotation) *
                Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
                Matrix.CreateTranslation(
                    new Vector3
                    (
                        graphicsDevice.PreferredBackBufferWidth * 0.5f,
                        graphicsDevice.PreferredBackBufferHeight * 0.5f,
                        0
                    )
            );

            return _transform;
        }

        //?
        public Vector2 get_mouse_vpos()
        {
            Vector2 mp = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
            return (mp + this._pos); // Camera is a member of the class in this example
            //return (mp  + _camera.pos);
        }

        //??
        public Vector2 get_mouse_vpos2()
        {
            Vector2 mp = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

            return ((mp * this._zoom) + this._pos); // Camera is a member of the class in this example
            //return ((mp * _camera.Zoom) + _camera.pos);
        }

        
       
    }
}  